﻿#include <iostream>

#include "MidiFile.h"

#include "MIDIReader.h"
#include "MLProgressbar.h"

using namespace nlohmann;

std::tuple<std::vector<NoteStream>, std::vector<VelocityStream>> read_midi(const std::string path, double frame_rate, size_t begin_secs, size_t end_secs, double blur_sigma, json& note_sizes) {
	std::cout << (char*)u8"正在读取MIDI文件……" << std::endl;
	std::ifstream f(path.c_str());
	if (!f.good()) {
		std::cerr << path.c_str() << std::endl;
		throw "该MIDI文件不存在或为空。";
	}
	f.close();
	smf::MidiFile file = smf::MidiFile((std::string&)path);
	file.linkNotePairs();
	file.doTimeAnalysis();
	size_t tpq = file.getTicksPerQuarterNote();
	int track_count = file.getTrackCount();
	smf::MidiEventList meta_track = file[0];
	std::vector<NoteStream> note_streams;
	std::vector<VelocityStream> velocity_streams;
	size_t* length_array = new size_t[track_count];
	size_t begin_frames = (size_t)round(frame_rate * begin_secs);
	size_t end_frames = (size_t)round(frame_rate * end_secs);
	size_t max_length = 0;
	std::cout << (char*)u8"正在解析MIDI文件……" << std::endl;
	MLProgressbar progressbar(track_count - 1, (char*)u8"解析MIDI文件");
	for (size_t i = 1; i < track_count; i++) {
		NoteStream note_stream(meta_track, file[i], frame_rate, tpq, note_sizes);
		note_streams.push_back(note_stream);
		VelocityStream velocity_stream(meta_track, file[i], frame_rate, blur_sigma * frame_rate, tpq, note_sizes);
		velocity_streams.push_back(velocity_stream);
		if (velocity_stream.length > max_length)max_length = velocity_stream.length;
		file[i].clear();
		progressbar.update();
	}
	meta_track.clear();
	file.clear();
	MLProgressbar progressbar2(track_count - 1, "对齐音符流");
	for (size_t i = 0; i < track_count - 1; i++) {
		note_streams[i].align(begin_frames);
		progressbar2.update();
	}
	MLProgressbar progressbar3(track_count - 1, "对齐力度流");
	for (size_t i = 0; i < track_count - 1; i++) {
		velocity_streams[i].align(max_length, begin_frames, end_frames);
		velocity_streams[i].gaussian_blur();
		progressbar3.update();
	}
	return std::make_tuple(note_streams, velocity_streams);
}
